// 父类
let Futher = {
  name: "",
  age: 50,
  sayAge() {
    return this.age;
  },
  setAge(newAge) {
    this.age = newAge;
  },
};

// 实现继承
function extend(obj, options = {}) {
  let newObj = JSON.parse(JSON.stringify(obj));
  for (let i in options) {
    if (options.hasOwnProperty(i)) {
      newObj[i] = options[i];
    }
  }
  return newObj;
}

// 想要添加的继承属性
let options = {
  age: 20, // 覆盖掉父类对象的age
  job: "",
  setJob(newJob) {
    this.job = newJob;
  },
  getJob() {
    return this.job;
  },
  parents: [], // 用于记录父母亲名字
};

// 创建子类
let Son = extend(Futher, options);

// 用于实例化对象
function create(obj) {
  function f() {}

  f.prototype = obj;

  let res = new f();

  // 只通过原型使用类的方法，属性添加到对象自身
  for (let i in obj) {
    if (obj.hasOwnProperty(i) && typeof obj[i] != "function") {
      if (typeof obj[i] === "object") {
        res[i] = JSON.parse(JSON.stringify(obj[i]));
      } else {
        res[i] = obj[i];
      }
    }
  }

  return res;
}

let son1 = create(Son);

son1.name = "小王";

son1.setJob("学生");

son1.parents.push(...["老王", "老妈"]);

let son2 = create(Son);

son2.name = "小李";

son2.setJob("警察");

son2.parents.push(...["老李", "老妈"]);

console.log(son1);

console.log(son2);

// 缺点在于没有实现 instance 和 constructor 反射功能，深拷贝降低性能 ，重写父类方法则直接覆盖 ， 创建出来的实例对象的原型上会有类对象的成员变量
// 优点在于放弃了构造函数的模式，成员方法只存在于类对象自身上，而不会在原型对象的原型上，更容易理解，通过对象组合实现继承功能
